package vn.edu.ptithcm.pim.util;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import vn.edu.ptithcm.pim.dom.Project;
import vn.edu.ptithcm.pim.dom.Task;

public class XMLUtil {
	private static Element createNewNodeFromOneTask(Task t, Document doc) {
		Element task = doc.createElement("task");
		task.setAttribute("id", t.getCode());

		Element name = doc.createElement("name");
		name.appendChild(doc.createTextNode(t.getSummary()));
		task.appendChild(name);

		Element est = doc.createElement("est");
		est.appendChild(doc.createTextNode(DateTimeUtil.dateToString(
				t.getStarttime(), "yyyy,MM,dd")));
		task.appendChild(est);

		Element duration = doc.createElement("duration");
		duration.appendChild(doc.createTextNode(String.valueOf(DateTimeUtil
				.diffInHours(t.getStarttime(), new Date()))));
		task.appendChild(duration);

		Element percentcompleted = doc.createElement("percentcompleted");
		percentcompleted
				.appendChild(doc.createTextNode(t.getPercentcomplete() == null ? "0"
						: t.getPercentcomplete().toString()));
		task.appendChild(percentcompleted);

		Element predecessortasks = doc.createElement("predecessortasks");
		predecessortasks.appendChild(doc.createTextNode(""));
		task.appendChild(predecessortasks);

		return task;
	}

	private static Element buildXMLFromTask(Task t, Document doc) {
		Element root = createNewNodeFromOneTask(t, doc);
		if (t.getTasksForTaskchildid().size() == 0) {
			return root;
		} else {
			Element childtasks = doc.createElement("childtasks");
			for (Task child : t.getTasksForTaskchildid()) {
				childtasks.appendChild(buildXMLFromTask(child, doc));
				root.appendChild(childtasks);
			}
		}
		return root;
	}

	public static String buildXMLFromProject(HttpServletRequest request,
			Project p, List<Task> tasks, String folder) {
		String xmlFilePath = "";
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		try {
			DocumentBuilder docBuilder = factory.newDocumentBuilder();
			Document doc = docBuilder.newDocument();
			Element projects = doc.createElement("projects");
			doc.appendChild(projects);

			Element project = doc.createElement("project");
			project.setAttribute("id", String.valueOf(p.getNumber()));
			project.setAttribute("name", p.getName());
			project.setAttribute("startdate",
					DateTimeUtil.dateToString(p.getStartdate(), "yyyy,MM,dd"));
			projects.appendChild(project);

			for (Task t : tasks) {
				project.appendChild(buildXMLFromTask(t, doc));
			}

			String path = request.getSession().getServletContext()
					.getRealPath("");
			int index = StringUtils.indexOf(path, "pim");
			path = path.substring(0, index) + folder + "\\";

			String fileName = System.currentTimeMillis() + ".xml";

			TransformerFactory tranFactory = TransformerFactory.newInstance();
			Transformer transformer = tranFactory.newTransformer();

			Source src = new DOMSource(doc);
			OutputStream writer = new FileOutputStream(path + "\\" + fileName);
			Result dest = new StreamResult(writer);
			transformer.transform(src, dest);

			xmlFilePath = "/" + folder + "/" + fileName;
			writer.close();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return xmlFilePath;
	}
}
